chore(repo): sync sample_app version to SDK + add TestFlight internal builds#2705
Conversation
* Set appversion to main sdk version * formatting
The cherry-picked commit set the sample_app version to 10.0.0; on master, the stream_chat SDK is 9.24.0. Running tools/generate_version.dart syncs sample_app/pubspec.yaml accordingly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 10 minutes and 20 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds internal TestFlight distribution: sample app version is synchronized, a Fastlane lane builds and uploads an app-store-signed IPA to TestFlight for internal testers, and a GitHub Actions job invokes that lane with required secrets. ChangesTestFlight Internal Distribution for Sample App
Sequence DiagramsequenceDiagram
participant GitHubActions as GitHub Actions (ios_testflight)
participant Fastlane as Fastlane lane (distribute_to_testflight_internal)
participant AppStoreConnect as App Store Connect/TestFlight
participant Crashlytics as Firebase Crashlytics
GitHubActions->>Fastlane: invoke distribute_to_testflight_internal (env: MATCH_PASSWORD, APPSTORE_API_KEY)
Fastlane->>Fastlane: match provisioning & increment build number
Fastlane->>Fastlane: build IPA (export_method: app-store)
Fastlane->>Crashlytics: upload dSYMs
Fastlane->>AppStoreConnect: upload IPA to TestFlight (groups: Internal Testers)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Match the v10 branch — the internal TestFlight lane should upload dSYMs to Firebase Crashlytics like distribute_to_testflight does, so symbolicated crash reports are available for internal-tester builds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tools/generate_version.dart (1)
54-59: ⚡ Quick winValidate the
pubspec.yamlreplacement before writing.This new path uses
replaceFirstwith an unanchoredversion: .+pattern and then always logs success. If the top-levelversion:line stops matching, the script silently leavessample_app/pubspec.yamlstale while claiming it was updated.Suggested hardening
- final updatedSampleAppPubspec = sampleAppPubspec.replaceFirst( - RegExp('version: .+'), - 'version: $cleanedVersion', - ); + final versionPattern = RegExp(r'^version:\s*.+$', multiLine: true); + if (!versionPattern.hasMatch(sampleAppPubspec)) { + throw StateError('Top-level version not found in $sampleAppPubspecPath'); + } + final updatedSampleAppPubspec = sampleAppPubspec.replaceFirst( + versionPattern, + 'version: $cleanedVersion', + );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tools/generate_version.dart` around lines 54 - 59, The current replacement using sampleAppPubspec.replaceFirst(RegExp('version: .+'), 'version: $cleanedVersion') may silently fail; change the regex to anchor to the top-level line (e.g. use multiline start '^version:\\s*.+', with RegExp(..., multiLine: true)) and validate that the replacement actually changed the string by comparing updatedSampleAppPubspec != sampleAppPubspec before calling File(...).writeAsString; if no change occurred, log an error (including the original pubspec snippet) and exit non-zero instead of claiming success. Ensure you reference the symbols updatedSampleAppPubspec, sampleAppPubspec.replaceFirst, RegExp('version: .+'), and File(sampleAppPubspecPath).writeAsString when making the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/distribute_internal.yml:
- Around line 159-199: Update the workflow steps to pin third‑party actions to
immutable commit SHAs (replace uses: webfactory/ssh-agent@v0.9.1,
maxim-lobanov/setup-xcode@v1, subosito/flutter-action@v2, ruby/setup-ruby@v1,
etc. with their corresponding full commit SHAs) and set persist-credentials:
false on the "Git Checkout" step (the step titled "Git Checkout" that uses
actions/checkout@v6) so the checkout token is not persisted to subsequent steps.
In `@sample_app/ios/fastlane/Fastfile`:
- Around line 133-144: The TestFlight internal lane currently calls build_ipa
and upload_to_testflight but does not upload dSYMs, so internal builds reach
Crashlytics without symbols; after the upload_to_testflight step in this lane,
add a call to upload_dsyms_to_crashlytics (using the dSYM/IPA output from
build_ipa, e.g. the same build output under root_path/build/ios) so Crashlytics
receives the symbol files; ensure the call occurs after upload_to_testflight and
references the correct artifact path used by build_ipa/ipa (e.g., the
ChatSample.ipa/dSYMs).
---
Nitpick comments:
In `@tools/generate_version.dart`:
- Around line 54-59: The current replacement using
sampleAppPubspec.replaceFirst(RegExp('version: .+'), 'version: $cleanedVersion')
may silently fail; change the regex to anchor to the top-level line (e.g. use
multiline start '^version:\\s*.+', with RegExp(..., multiLine: true)) and
validate that the replacement actually changed the string by comparing
updatedSampleAppPubspec != sampleAppPubspec before calling
File(...).writeAsString; if no change occurred, log an error (including the
original pubspec snippet) and exit non-zero instead of claiming success. Ensure
you reference the symbols updatedSampleAppPubspec,
sampleAppPubspec.replaceFirst, RegExp('version: .+'), and
File(sampleAppPubspecPath).writeAsString when making the fix.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 0da835e6-9327-46ab-a66d-7c62d7e19e66
📒 Files selected for processing (4)
.github/workflows/distribute_internal.ymlsample_app/ios/fastlane/Fastfilesample_app/pubspec.yamltools/generate_version.dart
| - name: Connect Bot | ||
| uses: webfactory/ssh-agent@v0.9.1 | ||
| with: | ||
| ssh-private-key: ${{ secrets.BOT_SSH_PRIVATE_KEY }} | ||
|
|
||
| - name: "Git Checkout" | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: maxim-lobanov/setup-xcode@v1 | ||
| with: | ||
| xcode-version: '26.3' | ||
|
|
||
| - name: "Install Flutter" | ||
| uses: subosito/flutter-action@v2 | ||
| with: | ||
| flutter-version: ${{ env.FLUTTER_VERSION }} | ||
| channel: stable | ||
| cache-key: flutter-:os:-:channel:-:version:-:arch:-:hash:-${{ hashFiles('**/pubspec.lock') }} | ||
|
|
||
| - name: "Disable Swift Package Manager" | ||
| run: flutter config --no-enable-swift-package-manager | ||
|
|
||
| - name: "Install Tools" | ||
| run: flutter pub global activate melos | ||
|
|
||
| - name: "Bootstrap Workspace" | ||
| run: melos bootstrap | ||
|
|
||
| - name: Setup Ruby | ||
| uses: ruby/setup-ruby@v1 | ||
| with: | ||
| bundler-cache: true | ||
| working-directory: sample_app/ios | ||
|
|
||
| - name: Distribute to TestFlight Internal | ||
| working-directory: sample_app/ios | ||
| env: | ||
| MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} | ||
| APPSTORE_API_KEY: ${{ secrets.APPSTORE_API_KEY }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/distribute_internal.yml"
echo "== File existence =="
ls -l "$FILE"
echo "== Show lines 130-230 =="
nl -ba "$FILE" | sed -n '130,230p'
echo "== Find all actions/checkout usages =="
rg -n "uses:\s*actions/checkout" "$FILE" || true
echo "== Show any persist-credentials settings =="
rg -n "persist-credentials" "$FILE" || true
echo "== Show all uses lines in the workflow (limited to within distribute_internal.yml) =="
rg -n "^\s*uses:\s*" "$FILE" | head -n 200Repository: GetStream/stream-chat-flutter
Length of output: 271
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/distribute_internal.yml"
nl -ba "$FILE" | sed -n '150,210p'Repository: GetStream/stream-chat-flutter
Length of output: 116
🏁 Script executed:
#!/bin/bash
set -euo pipefail
FILE=".github/workflows/distribute_internal.yml"
echo "== File existence =="
ls -l "$FILE"
echo "== Match actions/checkout usages =="
rg -n "uses:\s*actions/checkout" "$FILE" || true
echo "== Match persist-credentials settings =="
rg -n "persist-credentials" "$FILE" || true
echo "== Match all uses: lines (first 200) =="
rg -n "^\s*uses:\s*" "$FILE" | head -n 200 || true
echo "== Show file excerpt (lines 140-220) using awk =="
awk 'NR>=140 && NR<=220 {printf "%5d %s\n", NR, $0}' "$FILE" | sed -n '1,200p'Repository: GetStream/stream-chat-flutter
Length of output: 3350
Pin GitHub Actions to SHAs and prevent checkout token persistence
In the ios_testflight job, actions/checkout@v6 is used without persist-credentials: false, and multiple third-party actions use mutable version tags (webfactory/ssh-agent@v0.9.1, maxim-lobanov/setup-xcode@v1, subosito/flutter-action@v2, ruby/setup-ruby@v1). Pin each uses: to a full commit SHA, and set persist-credentials: false on the Git Checkout step.
🧰 Tools
🪛 zizmor (1.25.2)
[warning] 164-167: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 160-160: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 165-165: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 169-169: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 174-174: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
[error] 190-190: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/distribute_internal.yml around lines 159 - 199, Update the
workflow steps to pin third‑party actions to immutable commit SHAs (replace
uses: webfactory/ssh-agent@v0.9.1, maxim-lobanov/setup-xcode@v1,
subosito/flutter-action@v2, ruby/setup-ruby@v1, etc. with their corresponding
full commit SHAs) and set persist-credentials: false on the "Git Checkout" step
(the step titled "Git Checkout" that uses actions/checkout@v6) so the checkout
token is not persisted to subsequent steps.
Wrap the long print() call to satisfy the 80-col formatter the cherry-pick inherited (line was over the limit in the master format target). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2705 +/- ##
=======================================
Coverage 65.67% 65.67%
=======================================
Files 423 423
Lines 26694 26694
=======================================
Hits 17532 17532
Misses 9162 9162 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Summary
Cherry-picks two changes from the
v10.0.0branch ontomaster:chore(sample): Set appversion to main sdk version—tools/generate_version.dartnow also rewritessample_app/pubspec.yamlto match thestream_chatpackage version. Sample app version bumped from2.2.0to9.24.0to match master's current SDK.add internal testflight builds— newdistribute_to_testflight_internalFastlane lane andios_testflightjob indistribute_internal.ymlthat pushes builds to TestFlight's Internal Testers group on every push tomaster.Notes
ios_testflightworkflow job was adapted from chore(sample): Internal testflight builds #2508 to match master's existingiosjob conventions: addedmaxim-lobanov/setup-xcode@v1(xcode 26.3), added theDisable Swift Package Managerstep, and removed the redundantcache: trueflag.# TODO: Remove once feat/design-refresh is merged to mastercomment from the workflow — it's moot now that this lives on master.docs_screenshotsformatting tweaks from chore(sample): Set appversion to main sdk version #2678 were skipped — those files were deleted on master.Test plan
distribute_internal.ymlshould validate)dart run tools/generate_version.dartupdates bothversion.dartandsample_app/pubspec.yamlmaster, confirm theios_testflightjob successfully uploads to TestFlight Internal Testers🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Version